
/// ioctldbg.c
/// AIM Write Filter - Debug routines that translate IOCTL values to names etc.
/// 
/// Copyright (c) 2012-2025, Arsenal Consulting, Inc. (d/b/a Arsenal Recon) <http://www.ArsenalRecon.com>
/// This source code and API are available under the terms of the Affero General Public
/// License v3.
///
/// Please see LICENSE.txt for full license terms, including the availability of
/// proprietary exceptions.
/// Questions, comments, or requests for clarification: http://ArsenalRecon.com/contact/
///

#if DBG

#include "aimwrfltr.h"

#include <scsi.h>

#if defined(_M_ARM64)
#undef sprintf
#define sprintf(b, f, p) {b[0]=0;p;}
#endif

#define STR(x) #x

#define CASE_RETURN_NAME(value) case value: return #value;

#define FILE_DEVICE_MT_COMPOSITE        0x00000042
#define FILE_DEVICE_MT_TRANSPORT        0x00000043
#define FILE_DEVICE_BIOMETRIC		    0x00000044
#define FILE_DEVICE_PMI                 0x00000045
#define FILE_DEVICE_EHSTOR              0x00000046
#define FILE_DEVICE_DEVAPI              0x00000047
#define FILE_DEVICE_GPIO                0x00000048
#define FILE_DEVICE_USBEX               0x00000049
#define FILE_DEVICE_CONSOLE             0x00000050
#define FILE_DEVICE_NFP                 0x00000051
#define FILE_DEVICE_SYSENV              0x00000052
#define FILE_DEVICE_VIRTUAL_BLOCK       0x00000053
#define FILE_DEVICE_POINT_OF_SERVICE    0x00000054

#define FILE_DEVICE_IMDISK              0x00008372

#ifndef MOUNTDEVCONTROLTYPE
#define MOUNTDEVCONTROLTYPE             0x0000004D // 'M'
#endif

#define FTTYPE                          ((ULONG)'f')

PCSTR
AIMWrFltrGetIoctlDeviceTypeName(ULONG ctrlCode)
{
    ULONG DeviceType = DEVICE_TYPE_FROM_CTL_CODE(ctrlCode);

    switch (DeviceType)
    {
        CASE_RETURN_NAME(FILE_DEVICE_BEEP);
        CASE_RETURN_NAME(FILE_DEVICE_CD_ROM);
        CASE_RETURN_NAME(FILE_DEVICE_CD_ROM_FILE_SYSTEM);
        CASE_RETURN_NAME(FILE_DEVICE_CONTROLLER);
        CASE_RETURN_NAME(FILE_DEVICE_DATALINK);
        CASE_RETURN_NAME(FILE_DEVICE_DFS);
        CASE_RETURN_NAME(FILE_DEVICE_DISK);
        CASE_RETURN_NAME(FILE_DEVICE_DISK_FILE_SYSTEM);
        CASE_RETURN_NAME(FILE_DEVICE_FILE_SYSTEM);
        CASE_RETURN_NAME(FILE_DEVICE_INPORT_PORT);
        CASE_RETURN_NAME(FILE_DEVICE_KEYBOARD);
        CASE_RETURN_NAME(FILE_DEVICE_MAILSLOT);
        CASE_RETURN_NAME(FILE_DEVICE_MIDI_IN);
        CASE_RETURN_NAME(FILE_DEVICE_MIDI_OUT);
        CASE_RETURN_NAME(FILE_DEVICE_MOUSE);
        CASE_RETURN_NAME(FILE_DEVICE_MULTI_UNC_PROVIDER);
        CASE_RETURN_NAME(FILE_DEVICE_NAMED_PIPE);
        CASE_RETURN_NAME(FILE_DEVICE_NETWORK);
        CASE_RETURN_NAME(FILE_DEVICE_NETWORK_BROWSER);
        CASE_RETURN_NAME(FILE_DEVICE_NETWORK_FILE_SYSTEM);
        CASE_RETURN_NAME(FILE_DEVICE_NULL);
        CASE_RETURN_NAME(FILE_DEVICE_PARALLEL_PORT);
        CASE_RETURN_NAME(FILE_DEVICE_PHYSICAL_NETCARD);
        CASE_RETURN_NAME(FILE_DEVICE_PRINTER);
        CASE_RETURN_NAME(FILE_DEVICE_SCANNER);
        CASE_RETURN_NAME(FILE_DEVICE_SERIAL_MOUSE_PORT);
        CASE_RETURN_NAME(FILE_DEVICE_SERIAL_PORT);
        CASE_RETURN_NAME(FILE_DEVICE_SCREEN);
        CASE_RETURN_NAME(FILE_DEVICE_SOUND);
        CASE_RETURN_NAME(FILE_DEVICE_STREAMS);
        CASE_RETURN_NAME(FILE_DEVICE_TAPE);
        CASE_RETURN_NAME(FILE_DEVICE_TAPE_FILE_SYSTEM);
        CASE_RETURN_NAME(FILE_DEVICE_TRANSPORT);
        CASE_RETURN_NAME(FILE_DEVICE_UNKNOWN);
        CASE_RETURN_NAME(FILE_DEVICE_VIDEO);
        CASE_RETURN_NAME(FILE_DEVICE_VIRTUAL_DISK);
        CASE_RETURN_NAME(FILE_DEVICE_WAVE_IN);
        CASE_RETURN_NAME(FILE_DEVICE_WAVE_OUT);
        CASE_RETURN_NAME(FILE_DEVICE_8042_PORT);
        CASE_RETURN_NAME(FILE_DEVICE_NETWORK_REDIRECTOR);
        CASE_RETURN_NAME(FILE_DEVICE_BATTERY);
        CASE_RETURN_NAME(FILE_DEVICE_BUS_EXTENDER);
        CASE_RETURN_NAME(FILE_DEVICE_MODEM);
        CASE_RETURN_NAME(FILE_DEVICE_VDM);
        CASE_RETURN_NAME(FILE_DEVICE_MASS_STORAGE);
        CASE_RETURN_NAME(FILE_DEVICE_SMB);
        CASE_RETURN_NAME(FILE_DEVICE_KS);
        CASE_RETURN_NAME(FILE_DEVICE_CHANGER);
        CASE_RETURN_NAME(FILE_DEVICE_SMARTCARD);
        CASE_RETURN_NAME(FILE_DEVICE_ACPI);
        CASE_RETURN_NAME(FILE_DEVICE_DVD);
        CASE_RETURN_NAME(FILE_DEVICE_FULLSCREEN_VIDEO);
        CASE_RETURN_NAME(FILE_DEVICE_DFS_FILE_SYSTEM);
        CASE_RETURN_NAME(FILE_DEVICE_DFS_VOLUME);
        CASE_RETURN_NAME(FILE_DEVICE_SERENUM);
        CASE_RETURN_NAME(FILE_DEVICE_TERMSRV);
        CASE_RETURN_NAME(FILE_DEVICE_KSEC);
        CASE_RETURN_NAME(FILE_DEVICE_FIPS);
        CASE_RETURN_NAME(FILE_DEVICE_INFINIBAND);
        CASE_RETURN_NAME(FILE_DEVICE_VMBUS);
        CASE_RETURN_NAME(FILE_DEVICE_CRYPT_PROVIDER);
        CASE_RETURN_NAME(FILE_DEVICE_WPD);
        CASE_RETURN_NAME(FILE_DEVICE_BLUETOOTH);
        CASE_RETURN_NAME(FILE_DEVICE_MT_COMPOSITE);
        CASE_RETURN_NAME(FILE_DEVICE_MT_TRANSPORT);
        CASE_RETURN_NAME(FILE_DEVICE_BIOMETRIC);
        CASE_RETURN_NAME(FILE_DEVICE_PMI);
        CASE_RETURN_NAME(FILE_DEVICE_EHSTOR);
        CASE_RETURN_NAME(FILE_DEVICE_DEVAPI);
        CASE_RETURN_NAME(FILE_DEVICE_GPIO);
        CASE_RETURN_NAME(FILE_DEVICE_USBEX);
        CASE_RETURN_NAME(FILE_DEVICE_CONSOLE);
        CASE_RETURN_NAME(FILE_DEVICE_NFP);
        CASE_RETURN_NAME(FILE_DEVICE_SYSENV);
        CASE_RETURN_NAME(FILE_DEVICE_VIRTUAL_BLOCK);
        CASE_RETURN_NAME(FILE_DEVICE_POINT_OF_SERVICE);
        CASE_RETURN_NAME(FILE_DEVICE_IMDISK);
        CASE_RETURN_NAME(MOUNTDEVCONTROLTYPE);
        CASE_RETURN_NAME(FTTYPE);
    }

    static char buffer[11];
    if ((DeviceType >= 'A' && DeviceType <= 'Z') ||
        (DeviceType >= 'a' && DeviceType <= 'z'))
    {
        sprintf(buffer, "'%c'", (char)DeviceType);
    }
    else
    {
        sprintf(buffer, "0x%X", DeviceType);
    }
    return buffer;
}

PCSTR
AIMWrFltrGetIoctlMethodName(ULONG ctrlCode)
{
    ULONG Method = METHOD_FROM_CTL_CODE(ctrlCode);

    switch (Method)
    {
        CASE_RETURN_NAME(METHOD_BUFFERED);
        CASE_RETURN_NAME(METHOD_IN_DIRECT);
        CASE_RETURN_NAME(METHOD_OUT_DIRECT);
        CASE_RETURN_NAME(METHOD_NEITHER);
    }

    static char buffer[11];
    sprintf(buffer, "0x%X", Method);
    return buffer;
}

PCSTR
AIMWrFltrGetIoctlAccessName(ULONG ctrlCode)
{
    ULONG Access = ACCESS_FROM_CTL_CODE(ctrlCode);

    switch (Access)
    {
        CASE_RETURN_NAME(FILE_ANY_ACCESS);
        CASE_RETURN_NAME(FILE_READ_ACCESS);
        CASE_RETURN_NAME(FILE_WRITE_ACCESS);
        CASE_RETURN_NAME(FILE_READ_ACCESS | FILE_WRITE_ACCESS);
    }

    static char buffer[11];
    sprintf(buffer, "0x%X", Access);
    return buffer;
}

PCSTR
AIMWrFltrGetIoctlFunctionName(ULONG ctrlCode)
{
    ULONG Function = FUNCTN_FROM_CTL_CODE(ctrlCode);

    static char buffer[11];
    sprintf(buffer, "0x%X", Function);
    return buffer;
}

#endif
